package com.ys.erp.stage_mall_service.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ys.erp.common.enums.EnableEnum;
import com.ys.erp.common.util.MoneyUtil;
import com.ys.erp.common.util.YsThread;
import com.ys.erp.entity.data.bean.Order;
import com.ys.erp.entity.data.bean.OrderAfterSale;
import com.ys.erp.entity.data.bean.OrderGoods;
import com.ys.erp.entity.data.bean.ToShopOrder;
import com.ys.erp.entity.service.IOrderAfterSaleService;
import com.ys.erp.entity.service.IOrderGoodsService;
import com.ys.erp.entity.service.IOrderService;
import com.ys.erp.entity.service.IToShopOrderService;
import com.ys.erp.framework.bean.dto.StageEmpDTO;
import com.ys.erp.stage_mall_service.bean.condition.OrderStatCon;
import com.ys.erp.stage_mall_service.bean.vo.ToShopOrderRefundStatVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * @author lwj
 * @date 2025/5/20
 */
@Service
@RequiredArgsConstructor
@Slf4j
@RefreshScope
public class OrderStatService {

    private final IToShopOrderService iToShopOrderService;

    private final IOrderService iOrderService;

    private final IOrderGoodsService iOrderGoodsService;

    private final IOrderAfterSaleService iOrderAfterSaleService;

    /**
     * 到店付返款统计
     *
     * @param empDto                登录员工
     * @param con                   请求体
     * @return                      返款统计
     */
    public ToShopOrderRefundStatVO shopRefundStat(StageEmpDTO empDto, OrderStatCon.ToShopOrderRefundStatCon con) {
        QueryWrapper<ToShopOrder> toShopOrderQw = new QueryWrapper<>();
        toShopOrderQw.lambda().eq(ToShopOrder::getIsCancel, EnableEnum.NO.getEnable());
        toShopOrderQw.lambda().eq(ToShopOrder::getIsPay, EnableEnum.YES.getEnable());
        if (ObjectUtils.isEmpty(con.getShopCode())) {
            toShopOrderQw.lambda().eq(ToShopOrder::getShopCode, con.getShopCode());
        }
        if (ObjectUtils.isNotEmpty(con.getStartDate())) {
            toShopOrderQw.lambda().ge(ToShopOrder::getCreateTime, con.getStartDate() + " 00:00:00");
        }
        if (ObjectUtils.isNotEmpty(con.getEndDate())) {
            toShopOrderQw.lambda().le(ToShopOrder::getCreateTime, con.getStartDate() + " 23:59:59");
        }
        List<ToShopOrder> shopList = iToShopOrderService.list(toShopOrderQw);
        //按照店铺分组
        Map<String, List<ToShopOrder>> shopOrderMap =
                shopList.stream().collect(Collectors.groupingBy(ToShopOrder::getShopName));
        //异步查询每个店铺的订单信息并处理
        ToShopOrderRefundStatVO vo = new ToShopOrderRefundStatVO();
        AtomicLong totalMoney = new AtomicLong(0);
        AtomicLong saleTotalMoney = new AtomicLong(0);
        AtomicLong returnMoney = new AtomicLong(0);
        CompletableFuture<Void> execute = YsThread.execute(shopOrderMap.entrySet(), entry -> {
            List<ToShopOrder> toShopOrderList = entry.getValue();
            if (ObjectUtils.isEmpty(toShopOrderList)) {
                return;
            }
            //设置vo
            ToShopOrderRefundStatVO.ShopVO shopVo = new ToShopOrderRefundStatVO.ShopVO();
            shopVo.setToShopName(entry.getKey());
            //查询相关信息
            List<Long> orderIdList = toShopOrderList.stream().map(ToShopOrder::getOrderId).toList();
            //查询订单
            CompletableFuture<Map<Long, Order>> orderMapFuture = YsThread.execute(() -> {
                return iOrderService.listByIds(orderIdList).stream().collect(
                        Collectors.toMap(Order::getId, order -> order)
                );
            });
            //查询订单商品
            CompletableFuture<Map<Long, List<OrderGoods>>> orderGoodsMapFuture = YsThread.execute(() -> {
                return iOrderGoodsService.listByOrderIds(orderIdList).stream()
                        .collect(Collectors.groupingBy(OrderGoods::getOrderId));
            });
            //查询退款
            CompletableFuture<Map<Long, List<OrderAfterSale>>> afterSaleMapFuture = YsThread.execute(() -> {
                return iOrderAfterSaleService.listByOrderIds(orderIdList).stream()
                        .collect(Collectors.groupingBy(OrderAfterSale::getOrderId));
            });
            Map<Long, Order> orderMap = orderMapFuture.join();
            Map<Long, List<OrderAfterSale>> afterSaleMap = afterSaleMapFuture.join();
            for (ToShopOrder toShopOrder : toShopOrderList) {
                Order order = orderMap.get(toShopOrder.getOrderId());
                List<OrderAfterSale> afterSaleList = afterSaleMap.get(order.getId());
                //订单总额
                totalMoney.getAndAdd(order.getActualMoney() + totalMoney.longValue());
                //设置vo
                ToShopOrderRefundStatVO.ToShopOrderVO orderVo = new ToShopOrderRefundStatVO.ToShopOrderVO();
                orderVo.setOrderNo(toShopOrder.getOrderNo());
                //计算退款金额
                long refundWxMoney = 0L, refundYsMoney = 0L;
                if (ObjectUtils.isNotEmpty(afterSaleList)) {
                    for (OrderAfterSale afterSale : afterSaleList) {
                        refundWxMoney += afterSale.getRejectWxMoney();
                        refundYsMoney += afterSale.getRejectYsMoney();
                    }
                }
                long refundMoney = refundWxMoney + refundYsMoney;
                long wxMoney = order.getActualWxMoney() - refundWxMoney;
                long ysMoney = order.getActualYsMoney() - refundYsMoney;
                //设置订单销售额
                saleTotalMoney.getAndAdd(order.getActualMoney() - refundMoney);
                orderVo.setWxMoney(MoneyUtil.long2Str(wxMoney));
                orderVo.setYsMoney(MoneyUtil.long2Str(ysMoney));
                orderVo.setOrderTime(order.getOrderTime());
                String refundWxRatio = toShopOrder.getRefundWxRatio();
                String refundYsRatio = toShopOrder.getRefundYsRatio();
                orderVo.setWxRatio(refundWxRatio);
                orderVo.setYsRatio(refundYsRatio);
                BigDecimal ysValue = new BigDecimal(ysMoney)
                        .multiply(new BigDecimal(refundYsRatio).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                BigDecimal wxValue = new BigDecimal(wxMoney)
                        .multiply(new BigDecimal(refundWxRatio).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                long totalLongValue = wxValue.longValue() + ysValue.longValue();
                orderVo.setWxReturnMoney(MoneyUtil.long2Str(wxValue.longValue()));
                orderVo.setYsReturnMoney(MoneyUtil.long2Str(ysValue.longValue()));
                orderVo.setReturnTotalMoney(MoneyUtil.long2Str(totalLongValue));
                returnMoney.getAndAdd(totalLongValue);
                shopVo.getToShopOrderList().add(orderVo);
            }
            vo.getShopList().add(shopVo);
        });
        execute.join();
        vo.setOrderTotalMoney(MoneyUtil.long2Str(totalMoney.longValue()));
        vo.setSaleTotalMoney(MoneyUtil.long2Str(saleTotalMoney.longValue()));
        vo.setToShopOrderMoney(MoneyUtil.long2Str(returnMoney.longValue()));
        return vo;
    }

}
